using System.Collections;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

namespace MaterialUI
{
	[AddComponentMenu("MaterialUI/Material Ripple", 50)]
	[ExecuteInEditMode]
	public class MaterialRipple : MonoBehaviour, IPointerEnterHandler, IPointerDownHandler, IPointerUpHandler, IPointerExitHandler, IRippleCreator, ISelectHandler, IDeselectHandler, ISubmitHandler, IEventSystemHandler
	{
		public enum HighlightActive
		{
			Never,
			Hovered,
			Clicked
		}

		[SerializeField]
		private bool m_RipplesEnabled = true;

		[SerializeField]
		private bool m_AutoMatchGraphicColor = true;

		[SerializeField]
		private Graphic m_ColorMatchGraphic;

		[SerializeField]
		private RippleData m_RippleData = new RippleData();

		[SerializeField]
		private Graphic m_HighlightGraphic;

		[SerializeField]
		private HighlightActive m_HighlightWhen = HighlightActive.Clicked;

		[SerializeField]
		private bool m_AutoHighlightColor = true;

		[SerializeField]
		private Color m_HighlightColor = Color.black;

		[SerializeField]
		private bool m_ToggleMask = true;

		[SerializeField]
		private bool m_CheckForScroll;

		private int m_RippleCount;

		private Mask m_Mask;

		[SerializeField]
		private float m_AutoHighlightBlendAmount = 0.2f;

		private Ripple m_CurrentRipple;

		private Color m_NormalColor;

		private Color m_CurrentColor;

		private int m_AnimState;

		private float m_AnimStartTime;

		private float m_AnimDeltaTime;

		private float m_AnimDuration;

		private bool m_ImageIsTransparent;

		private bool m_Clicked;

		public bool ripplesEnabled
		{
			get
			{
				return m_RipplesEnabled;
			}
			set
			{
				m_RipplesEnabled = value;
			}
		}

		public bool autoMatchGraphicColor
		{
			get
			{
				return m_AutoMatchGraphicColor;
			}
			set
			{
				m_AutoMatchGraphicColor = value;
				RefreshSettings();
			}
		}

		public Graphic colorMatchGraphic
		{
			get
			{
				return m_ColorMatchGraphic;
			}
			set
			{
				m_ColorMatchGraphic = value;
				RefreshSettings();
			}
		}

		public RippleData rippleData
		{
			get
			{
				return m_RippleData;
			}
			set
			{
				m_RippleData = value;
			}
		}

		public Color rippleColor
		{
			get
			{
				return m_RippleData.Color;
			}
			set
			{
				m_RippleData.Color = value;
				RefreshSettings();
			}
		}

		public Graphic highlightGraphic
		{
			get
			{
				if (m_HighlightGraphic == null && m_RippleData.RippleParent != null)
				{
					m_HighlightGraphic = m_RippleData.RippleParent.GetComponent<Graphic>();
				}
				return m_HighlightGraphic;
			}
			set
			{
				m_HighlightGraphic = value;
			}
		}

		public HighlightActive highlightWhen
		{
			get
			{
				return m_HighlightWhen;
			}
			set
			{
				m_HighlightWhen = value;
			}
		}

		public bool autoHighlightColor
		{
			get
			{
				return m_AutoHighlightColor;
			}
			set
			{
				m_AutoHighlightColor = value;
				if (value)
				{
					RefreshSettings();
				}
			}
		}

		public Color highlightColor
		{
			get
			{
				return m_HighlightColor;
			}
			set
			{
				m_HighlightColor = value;
			}
		}

		public bool toggleMask
		{
			get
			{
				return m_ToggleMask;
			}
			set
			{
				m_ToggleMask = value;
			}
		}

		public bool checkForScroll
		{
			get
			{
				return m_CheckForScroll;
			}
			set
			{
				m_CheckForScroll = value;
			}
		}

		public int rippleCount => m_RippleCount;

		public Mask mask
		{
			get
			{
				if (m_Mask == null && m_ToggleMask && highlightGraphic != null)
				{
					m_Mask = highlightGraphic.GetAddComponent<Mask>();
				}
				return m_Mask;
			}
		}

		public float autoHighlightBlendAmount
		{
			get
			{
				return m_AutoHighlightBlendAmount;
			}
			set
			{
				m_AutoHighlightBlendAmount = Mathf.Clamp(value, 0f, 1f);
			}
		}

		private void Start()
		{
			if (!m_RippleData.RippleParent)
			{
				Image[] componentsInChildren = GetComponentsInChildren<Image>();
				for (int i = 0; i < componentsInChildren.Length; i++)
				{
					if (!componentsInChildren[i].GetComponent<AnimatedShadow>())
					{
						m_RippleData.RippleParent = componentsInChildren[i].transform;
						m_HighlightGraphic = null;
						break;
					}
				}
				Graphic componentInChildren = GetComponentInChildren<Graphic>();
				if (componentInChildren != null)
				{
					m_RippleData.RippleParent = componentInChildren.transform;
				}
			}
			if (Application.isPlaying)
			{
				RefreshSettings();
			}
		}

		private void Update()
		{
			if (!highlightGraphic)
			{
				m_AnimState = 0;
			}
			else if (m_AnimState == 1)
			{
				m_AnimDeltaTime = Time.realtimeSinceStartup - m_AnimStartTime;
				if (m_AnimDeltaTime <= m_AnimDuration)
				{
					highlightGraphic.color = Tween.CubeOut(m_CurrentColor, highlightColor, m_AnimDeltaTime, m_AnimDuration);
					CheckTransparency();
				}
				else
				{
					highlightGraphic.color = highlightColor;
					CheckTransparency();
					m_AnimState = 0;
				}
			}
			else if (m_AnimState == 2)
			{
				m_AnimDeltaTime = Time.realtimeSinceStartup - m_AnimStartTime;
				if (m_AnimDeltaTime <= m_AnimDuration)
				{
					highlightGraphic.color = Tween.CubeOut(m_CurrentColor, (!(m_NormalColor.a < 0.015f)) ? m_NormalColor : m_HighlightColor.WithAlpha(0f), m_AnimDeltaTime, m_AnimDuration);
					CheckTransparency();
				}
				else
				{
					highlightGraphic.color = m_NormalColor;
					CheckTransparency();
					m_AnimState = 0;
				}
			}
		}

		private void CheckTransparency()
		{
			if (!m_ImageIsTransparent)
			{
				return;
			}
			Color color = this.highlightGraphic.color;
			if (color.a <= 0.015f)
			{
				Graphic highlightGraphic = this.highlightGraphic;
				Color color2 = this.highlightGraphic.color;
				float r = color2.r;
				Color color3 = this.highlightGraphic.color;
				float g = color3.g;
				Color color4 = this.highlightGraphic.color;
				highlightGraphic.color = new Color(r, g, color4.b, (m_RippleCount <= 0) ? 0f : 0.015f);
				if (m_Mask != null)
				{
					mask.showMaskGraphic = false;
				}
			}
			else if (m_Mask != null)
			{
				m_Mask.showMaskGraphic = true;
			}
		}

		public void SetGraphicColor(Color color, bool animate = true)
		{
			if (animate)
			{
				m_NormalColor = color;
				if (m_AutoHighlightColor)
				{
					m_HighlightColor = MaterialColor.HighlightColor(m_NormalColor, rippleData.Color, m_AutoHighlightBlendAmount);
				}
				m_CurrentColor = highlightGraphic.color;
				m_AnimStartTime = Time.realtimeSinceStartup;
				if (m_AnimState == 0)
				{
					m_AnimState = 2;
				}
			}
			else
			{
				m_NormalColor = color;
				if (m_AutoHighlightColor)
				{
					m_HighlightColor = MaterialColor.HighlightColor(m_NormalColor, rippleData.Color, m_AutoHighlightBlendAmount);
				}
				highlightGraphic.color = ((m_AnimState != 1) ? m_NormalColor : m_HighlightColor);
				m_AnimState = 0;
			}
		}

		public void RefreshSettings()
		{
			m_AnimDuration = 4f / rippleData.Speed;
			RefreshGraphicMatchColor();
			RefreshTransparencySettings();
			RefreshAutoHighlightColor();
		}

		public void RefreshTransparencySettings()
		{
			if ((bool)highlightGraphic)
			{
				Color color = highlightGraphic.color;
				m_ImageIsTransparent = (color.a == 0f && toggleMask);
				if (m_ToggleMask && (bool)highlightGraphic.GetComponent<Mask>())
				{
					UnityEngine.Object.Destroy(highlightGraphic.GetComponent<Mask>());
				}
			}
		}

		public void RefreshGraphicMatchColor()
		{
			if (m_AutoMatchGraphicColor && m_ColorMatchGraphic != null)
			{
				if (m_AutoHighlightColor)
				{
					rippleData.Color = m_ColorMatchGraphic.color;
				}
				else
				{
					highlightColor = m_ColorMatchGraphic.color;
				}
			}
			RefreshAutoHighlightColor();
		}

		public void RefreshAutoHighlightColor()
		{
			if (!highlightGraphic)
			{
				return;
			}
			m_NormalColor = highlightGraphic.color;
			if (autoHighlightColor && highlightWhen != 0)
			{
				this.highlightColor = MaterialColor.HighlightColor(m_NormalColor, rippleData.Color, m_AutoHighlightBlendAmount);
				if (m_ImageIsTransparent)
				{
					Color highlightColor = this.highlightColor;
					float r = highlightColor.r;
					Color highlightColor2 = this.highlightColor;
					float g = highlightColor2.g;
					Color highlightColor3 = this.highlightColor;
					m_NormalColor = new Color(r, g, highlightColor3.b, 0f);
					highlightGraphic.color = m_NormalColor;
				}
			}
		}

		public void OnPointerEnter(PointerEventData eventData)
		{
			if (base.enabled && highlightWhen == HighlightActive.Hovered)
			{
				Highlight(1);
			}
		}

		public void OnPointerDown(PointerEventData eventData)
		{
			m_Clicked = true;
			DestroyRipple();
			if (!base.enabled)
			{
				return;
			}
			DestroyRipple();
			if (checkForScroll)
			{
				StartCoroutine(ScrollCheck());
				return;
			}
			CreateRipple(eventData.position);
			if (highlightWhen == HighlightActive.Clicked)
			{
				Highlight(1);
			}
		}

		public void OnPointerUp(PointerEventData eventData)
		{
			DestroyRipple();
			m_Clicked = false;
			if (highlightWhen == HighlightActive.Clicked)
			{
				Highlight(2);
			}
		}

		public void OnPointerExit(PointerEventData eventData)
		{
			DestroyRipple();
			m_Clicked = false;
			if (highlightWhen != 0)
			{
				Highlight(2);
			}
		}

		private void Highlight(int state)
		{
			if ((bool)highlightGraphic)
			{
				Color color = highlightGraphic.color;
				m_CurrentColor = ((!(color.a < 0.015f)) ? highlightGraphic.color : highlightColor.WithAlpha(0f));
				m_AnimStartTime = Time.realtimeSinceStartup;
				m_AnimState = state;
			}
		}

		private void CreateRipple(Vector2 position, bool oscillate = false)
		{
			if (m_RipplesEnabled)
			{
				m_CurrentRipple = RippleManager.instance.GetRipple();
				m_CurrentRipple.Setup(rippleData, position, this, oscillate);
				m_CurrentRipple.Expand();
			}
		}

		private void DestroyRipple()
		{
			if ((bool)m_CurrentRipple)
			{
				m_CurrentRipple.Contract();
				m_CurrentRipple = null;
			}
		}

		private void OnFirstRippleCreate()
		{
			if (m_ImageIsTransparent)
			{
				Color color = this.highlightGraphic.color;
				if (color.a < 0.015f)
				{
					Graphic highlightGraphic = this.highlightGraphic;
					Color color2 = this.highlightGraphic.color;
					float r = color2.r;
					Color color3 = this.highlightGraphic.color;
					float g = color3.g;
					Color color4 = this.highlightGraphic.color;
					highlightGraphic.color = new Color(r, g, color4.b, 0.015f);
				}
			}
			if (toggleMask)
			{
				mask.enabled = true;
			}
		}

		private void OnLastRippleDestroy()
		{
			if (!toggleMask)
			{
				return;
			}
			if (m_ImageIsTransparent)
			{
				Color color = this.highlightGraphic.color;
				if (color.a <= 0.015f)
				{
					Graphic highlightGraphic = this.highlightGraphic;
					Color color2 = this.highlightGraphic.color;
					float r = color2.r;
					Color color3 = this.highlightGraphic.color;
					float g = color3.g;
					Color color4 = this.highlightGraphic.color;
					highlightGraphic.color = new Color(r, g, color4.b, 0f);
				}
			}
			UnityEngine.Object.Destroy(m_Mask);
		}

		public void OnCreateRipple()
		{
			if (rippleCount == 0)
			{
				OnFirstRippleCreate();
			}
			m_RippleCount++;
		}

		public void OnDestroyRipple()
		{
			m_RippleCount--;
			if (rippleCount == 0)
			{
				OnLastRippleDestroy();
			}
		}

		private IEnumerator ScrollCheck()
		{
			Vector2 startPos = UnityEngine.Input.mousePosition;
			yield return new WaitForSeconds(0.04f);
			Vector2 endPos = UnityEngine.Input.mousePosition;
			if (Vector2.Distance(startPos, endPos) < 2f)
			{
				CreateRipple(startPos);
				if (highlightWhen == HighlightActive.Clicked)
				{
					Highlight(1);
				}
			}
		}

		private IEnumerator SelectCheck()
		{
			yield return new WaitForEndOfFrame();
			if (!m_Clicked)
			{
				CreateRipple(m_RippleData.RippleParent.position, oscillate: true);
				if (highlightWhen == HighlightActive.Hovered)
				{
					Highlight(1);
				}
			}
		}

		public void OnSelect(BaseEventData eventData)
		{
			StartCoroutine(SelectCheck());
		}

		public void OnDeselect(BaseEventData eventData)
		{
			DestroyRipple();
			if (highlightWhen == HighlightActive.Hovered)
			{
				Highlight(2);
			}
			m_Clicked = false;
		}

		public void OnSubmit(BaseEventData eventData)
		{
			DestroyRipple();
			if (highlightWhen == HighlightActive.Hovered)
			{
				Highlight(2);
			}
			StartCoroutine(SelectCheck());
		}
	}
}
